home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / jove4.9 / part04 < prev    next >
Encoding:
Internet Message Format  |  1988-04-25  |  56.1 KB

  1. Subject:  v14i060:  Jove, an emacs variant, version 4.9, Part04/21
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Jonathan Payne <jpayne@cs.rochester.edu>
  7. Posting-number: Volume 14, Issue 60
  8. Archive-name: jove4.9/part04
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 4 (of 21)."
  17. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  18. if test -f './Makefile' -a "${1}" != "-c" ; then 
  19.   echo shar: Will not clobber existing file \"'./Makefile'\"
  20. else
  21. echo shar: Extracting \"'./Makefile'\" \(8207 characters\)
  22. sed "s/^X//" >'./Makefile' <<'END_OF_FILE'
  23. X###########################################################################
  24. X# This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE #
  25. X# is provided to you without charge, and with no warranty.  You may give  #
  26. X# away copies of JOVE, including sources, provided that this notice is    #
  27. X# included in all the files.                                              #
  28. X###########################################################################
  29. X
  30. X# TMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove.  If
  31. X# your system does not remove subdirectories of /tmp on reboot (lots do
  32. X# remove them these days) then it makes sense to make TMPDIR be /tmp/jove.
  33. X# But if you want to recover buffers on system crashes, you should create a
  34. X# directory that doesn't get clearned upon reboot, and use that instead.
  35. X# You would probably want to clean out that directory periodically with
  36. X# /etc/cron.  LIBDIR is for online documentation, the PORTSRV process,
  37. X# RECOVER, and the system-wide .joverc file.  BINDIR is where to put the
  38. X# executables JOVE and TEACHJOVE.  MANDIR is where the manual pages go for
  39. X# JOVE, RECOVER and TEACHJOVE.  MANEXT is the extension for the man pages,
  40. X# e.g., jove.1 or jove.l or jove.m.
  41. X
  42. DESTDIR =
  43. TMPDIR = /tmp
  44. LIBDIR = /usr/local/lib/jove
  45. BINDIR = /usr/local
  46. MANDIR = /usr/man/manl
  47. MANEXT = l
  48. SHELL = /bin/csh
  49. X
  50. X# These should all just be right if the above ones are.
  51. JOVE = $(DESTDIR)$(BINDIR)/jove
  52. TEACHJOVE = $(DESTDIR)$(BINDIR)/teachjove
  53. RECOVER = $(DESTDIR)$(LIBDIR)/recover
  54. PORTSRV = $(DESTDIR)$(LIBDIR)/portsrv
  55. JOVERC = $(DESTDIR)$(LIBDIR)/.joverc
  56. CMDS.DOC = $(DESTDIR)$(LIBDIR)/cmds.doc
  57. TEACH-JOVE = $(DESTDIR)$(LIBDIR)/teach-jove
  58. JOVEM = $(DESTDIR)$(MANDIR)/jove.$(MANEXT)
  59. TEACHJOVEM = $(DESTDIR)$(MANDIR)/teachjove.$(MANEXT)
  60. X
  61. X# Select the right libraries for your system.
  62. X#    2.10BSD:LIBS = -ltermcap
  63. X#    v7:    LIBS = -ltermcap
  64. X#    4.1BSD:    LIBS = -ltermcap -ljobs
  65. X#    4.2BSD:    LIBS = -ltermcap
  66. X#    4.3BSD:    LIBS = -ltermcap
  67. X#    SysV Rel. 2: LIBS = -lcurses
  68. X#    SCO Xenix: LIBS = -ltermcap -lx
  69. X
  70. LIBS = -ltermcap
  71. X
  72. X# If you are not VMUNIX (vax running Berkeley Version 4), you must specify
  73. X# the -i flags (split I/D space) and maybe the -x option (for adb to work).
  74. X#    2.10BSD:LDFLAGS =
  75. X#    v7:    LDFLAGS =
  76. X#    4.1BSD:    LDFLAGS =
  77. X#    4.2BSD:    LDFLAGS =
  78. X#    4.3BSD:    LDFLAGS =
  79. X#    SysV Rel. 2: LDFLAGS = -Ml
  80. X#    SCO Xenix: LDFLAGS = -Ml -F 3000
  81. X#
  82. X# SEPFLAG should be:
  83. X#    not on a PDP-11:        SEPFLAG =
  84. X#    PDP-11 with separate I&D:    SEPFLAG = -i
  85. X#    PDP-11 without separate I&D:    SEPFLAG = -n
  86. X#
  87. X
  88. LDFLAGS = 
  89. X
  90. SEPFLAG =
  91. X
  92. X# for SCO Xenix, set
  93. X#    MEMFLAGS = -Mle
  94. X#    CFLAGS = -LARGE -O -F 3000 -K -Mle  (say -Mle2 for an 80286)
  95. X
  96. CFLAGS = -O 
  97. X
  98. BASESEG = funcdefs.o keymaps.o argcount.o ask.o buf.o ctype.o delete.o \
  99. X      disp.o insert.o io.o jove.o malloc.o marks.o misc.o re.o \
  100. X      screen.o table.o tune.o util.o vars.o version.o
  101. OVLAY1 = abbrev.o rec.o paragraph.o fmt.o
  102. OVLAY2 = c.o wind.o fp.o move.o
  103. OVLAY3 = extend.o macros.o
  104. OVLAY4 = iproc.o re1.o
  105. OVLAY5 = proc.o scandir.o term.o case.o
  106. X
  107. OBJECTS = $(BASESEG) $(OVLAY1) $(OVLAY2) $(OVLAY3) $(OVLAY4) $(OVLAY5)
  108. X
  109. C_SRC = funcdefs.c abbrev.c argcount.c ask.c buf.c c.c case.c ctype.c \
  110. X    delete.c disp.c extend.c fp.c fmt.c insert.c io.c iproc.c \
  111. X    jove.c macros.c malloc.c marks.c misc.c move.c paragraph.c \
  112. X    proc.c re.c re1.c rec.c scandir.c screen.c table.c term.c util.c \
  113. X    vars.c version.c wind.c getch.c mac.c
  114. X
  115. SOURCES = $(C_SRC) portsrv.c recover.c setmaps.c teachjove.c
  116. X
  117. HEADERS = ctype.h io.h jove.h re.h rec.h table.h temp.h termcap.h \
  118. X    tune.h externs.h mac.h
  119. X
  120. DOCS =    doc/cmds.doc.nr doc/example.rc doc/jove.1 doc/jove.2 doc/jove.3 \
  121. X    doc/jove.4 doc/jove.5 doc/jove.nr doc/system.rc \
  122. X    doc/teach-jove doc/teachjove.nr doc/README doc/jove.qref
  123. X
  124. MISC = Makefile Ovmakefile Makefile.dos tune.dos tune.template \
  125. X    README Readme.dos Readme.mac iproc-pipes.c iproc-ptys.c
  126. X
  127. SUPPORT = teachjove.c recover.c setmaps.c portsrv.c keymaps.txt \
  128. X    macvert.c menumaps.txt mjovers.Hqx
  129. X
  130. BACKUPS = $(HEADERS) $(C_SRC) $(DOCS) $(SUPPORT) $(MISC)
  131. X
  132. all:    sdate xjove recover teachjove portsrv macvert edate
  133. X
  134. sdate:
  135. X    @echo "**** make started at `date` ****"
  136. X
  137. edate:
  138. X    @echo "**** make completed at `date` ****"
  139. X
  140. xjove:    $(OBJECTS)
  141. X    $(CC) $(LDFLAGS) -o xjove $(OBJECTS) $(LIBS)
  142. X    @-size xjove
  143. X
  144. gjove:    $(OBJECTS)
  145. X    ld -X /lib/gcrt0.o -o gjove $(OBJECTS) -lc $(LIBS)
  146. X    @-size gjove
  147. X
  148. ovjove:    $(OBJECTS)
  149. X    ld $(SEPFLAG) $(LDFLAGS) -X /lib/crt0.o \
  150. X        -Z $(OVLAY1) \
  151. X        -Z $(OVLAY2) \
  152. X        -Z $(OVLAY3) \
  153. X        -Z $(OVLAY4) \
  154. X        -Z $(OVLAY5) \
  155. X        -Y $(BASESEG) \
  156. X        -o xjove $(LIBS) -lc; \
  157. X    @-size xjove
  158. X
  159. portsrv:    portsrv.o
  160. X    $(CC) $(LDFLAGS) -o portsrv $(SEPFLAG) portsrv.o $(LIBS)
  161. X
  162. recover:    recover.o tune.o rec.h temp.h
  163. X    $(CC) $(LDFLAGS) -o recover $(SEPFLAG) recover.o tune.o $(LIBS)
  164. X
  165. teachjove:    teachjove.o
  166. X    $(CC) $(LDFLAGS) -o teachjove $(SEPFLAG) teachjove.o $(LIBS)
  167. X
  168. setmaps:    setmaps.o funcdefs.c
  169. X    $(CC) $(LDFLAGS) -o setmaps setmaps.o
  170. X
  171. teachjove.o:    teachjove.c /usr/include/sys/types.h /usr/include/sys/file.h
  172. X    cc -c $(CFLAGS) -DTEACHJOVE=\"$(TEACH-JOVE)\" teachjove.c
  173. X
  174. X# don't optimize setmaps.c because it produces bad code in some places
  175. X# for some reason
  176. setmaps.o:    funcdefs.c keymaps.txt
  177. X    $(CC) $(MEMFLAGS) -c setmaps.c
  178. X
  179. X# ignore error messages from setmaps
  180. X# it doesn't understand ifdefs
  181. X
  182. keymaps.c:    setmaps keymaps.txt
  183. X    -setmaps < keymaps.txt > keymaps.c
  184. X
  185. keymaps.o:    keymaps.c jove.h
  186. X
  187. tune.c: Makefile tune.template
  188. X    @echo "/* Changes should be made in Makefile, not to this file! */" > tune.c
  189. X    @echo "" >> tune.c
  190. X    @sed -e 's;TMPDIR;$(TMPDIR);' \
  191. X         -e 's;LIBDIR;$(LIBDIR);' \
  192. X         -e 's;BINDIR;$(BINDIR);' \
  193. X         -e 's;SHELL;$(SHELL);' tune.template >> tune.c
  194. X
  195. iproc.o: iproc-ptys.c iproc-pipes.c iproc.c
  196. X    $(CC) -c $(CFLAGS) iproc.c
  197. X
  198. macvert:    macvert.c
  199. X    $(CC) $(CFLAGS) -o macvert macvert.c
  200. X
  201. X# install doesn't work for Xenix (no install program)
  202. X
  203. install: $(DESTDIR)$(LIBDIR) $(TEACH-JOVE) $(CMDS.DOC) $(JOVERC) \
  204. X     $(PORTSRV) $(RECOVER) $(JOVE) $(TEACHJOVE) $(JOVEM) \
  205. X     $(RECOVERM) $(TEACHJOVEM)
  206. X
  207. X$(DESTDIR)$(LIBDIR):
  208. X    -mkdir $(DESTDIR)$(LIBDIR)
  209. X
  210. X$(TEACH-JOVE): doc/teach-jove
  211. X    install -c -m 644 doc/teach-jove $(TEACH-JOVE)
  212. X
  213. doc/cmds.doc:    doc/cmds.doc.nr doc/jove.4 doc/jove.5
  214. X    nroff doc/cmds.doc.nr doc/jove.4 doc/jove.5 > doc/cmds.doc
  215. X
  216. X$(CMDS.DOC): doc/cmds.doc
  217. X    install -c -m 644 doc/cmds.doc $(CMDS.DOC)
  218. X
  219. X$(JOVERC): doc/system.rc
  220. X    install -c -m 644 doc/system.rc $(JOVERC)
  221. X
  222. X$(PORTSRV): portsrv
  223. X    install -c -s -m 755 portsrv $(PORTSRV)
  224. X
  225. X$(RECOVER): recover
  226. X    install -c -s -m 755 recover $(RECOVER)
  227. X
  228. X$(JOVE): xjove
  229. X    install -c -m 755 xjove $(JOVE)
  230. X
  231. X$(TEACHJOVE): teachjove
  232. X    install -c -s -m 755 teachjove $(TEACHJOVE)
  233. X
  234. X$(JOVEM): doc/jove.nr
  235. X    @sed -e 's;TMPDIR;$(TMPDIR);' \
  236. X         -e 's;LIBDIR;$(LIBDIR);' \
  237. X         -e 's;SHELL;$(SHELL);' doc/jove.nr > /tmp/jove.nr
  238. X    install -m 644 /tmp/jove.nr $(JOVEM)
  239. X
  240. X$(TEACHJOVEM): doc/teachjove.nr
  241. X    @sed -e 's;TMPDIR;$(TMPDIR);' \
  242. X         -e 's;LIBDIR;$(LIBDIR);' \
  243. X         -e 's;SHELL;$(SHELL);' doc/teachjove.nr > /tmp/teachjove.nr
  244. X    install -m 644 /tmp/teachjove.nr $(TEACHJOVEM)
  245. X
  246. echo:
  247. X    @echo $(C-FILES) $(HEADERS)
  248. X
  249. lint:
  250. X    lint -n $(C_SRC) tune.c keymaps.c
  251. X    @echo Done
  252. X
  253. tags:
  254. X    ctags -w $(C_SRC) $(HEADERS) iproc-ptys.c
  255. X
  256. ciall:
  257. X    ci $(BACKUPS)
  258. X
  259. coall:
  260. X    co $(BACKUPS)
  261. X
  262. jove.shar:
  263. X    shar $(BACKUPS) > jove.shar
  264. X
  265. backup: $(BACKUPS)
  266. X    tar chf backup $(BACKUPS)
  267. X
  268. tape-backup:
  269. X    tar c $(BACKUPS)
  270. X
  271. srcdownload:
  272. X    kermit -s $(SUPPORT) $(MISC) $(HEADERS) $(C_SRC)
  273. X
  274. docdownload:
  275. X    kermit -s $(DOCS)
  276. X
  277. touch:
  278. X    touch $(OBJECTS)
  279. X
  280. clean:
  281. X    rm -f a.out core *.o keymaps.c tune.c xjove portsrv recover setmaps \
  282. X    teachjove macvert
  283. X
  284. X# This version only works under 4.3BSD
  285. X#depend:
  286. X#    for i in ${SOURCES} ; do \
  287. X#        cc -M ${CFLAGS} $$i | awk ' { if ($$1 != prev) \
  288. X#            { if (rec != "") print rec; rec = $$0; prev = $$1; } \
  289. X#            else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
  290. X#            else rec = rec " " $$2 } } \
  291. X#            END { print rec } ' >> makedep; done
  292. X#    echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
  293. X#    echo '$$r makedep' >>eddep
  294. X#    echo 'w' >>eddep
  295. X#    cp Makefile Makefile.bak
  296. X#    ed - Makefile < eddep
  297. X#    rm eddep makedep
  298. X#    echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
  299. X#    echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
  300. X#    echo '# see make depend above' >> Makefile
  301. X#
  302. X## DO NOT DELETE THIS LINE -- make depend uses it
  303. END_OF_FILE
  304. if test 8207 -ne `wc -c <'./Makefile'`; then
  305.     echo shar: \"'./Makefile'\" unpacked with wrong size!
  306. fi
  307. # end of './Makefile'
  308. fi
  309. if test -f './README' -a "${1}" != "-c" ; then 
  310.   echo shar: Will not clobber existing file \"'./README'\"
  311. else
  312. echo shar: Extracting \"'./README'\" \(8923 characters\)
  313. sed "s/^X//" >'./README' <<'END_OF_FILE'
  314. X###########################################################################
  315. X# This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE #
  316. X# is provided to you without charge, and with no warranty.  You may give  #
  317. X# away copies of JOVE, including sources, provided that this notice is    #
  318. X# included in all the files.                                              #
  319. X###########################################################################
  320. X
  321. To make JOVE edit Makefile to set the right directories for the binaries,
  322. on line documentation, the man pages, and the TMP files and select the
  323. appropriate load command (see SEPFLAG in Makefile).  (IMPORTANT! read the
  324. Makefile carefully.)  "tune.c" will be created from "tune.template" by
  325. MAKE automatically, and it will use the directories you specified in the
  326. Makefile.  (NOTE:  You should never edit tune.c directly because your
  327. changes will be undone by the next make.  If you want to make a change to
  328. a part of tune.c that isn't a directory name, you should edit
  329. tune.template.)  Next you must edit "tune.h" selecting the compile time
  330. options you care about.  See below for a description of all the compile
  331. time options.  You can type "make" to compile XJOVE, PORTSRV (this is
  332. compiled but not used on 4.2+ systems), RECOVER TEACHJOVE, and
  333. MACVERT.  NOTE:  make won't work if it fires up /bin/csh for the shell
  334. commands.  Test them out to see if they work.  If they do, type "make
  335. install" to install everything where it belongs.
  336. X
  337. Here are some things to consider for deciding where to put the tmp files.
  338. TMPDIR is where the tmp files get stored, usually /tmp or /tmp/jove.  If
  339. your system does not remove subdirectories of /tmp on reboot (lots do
  340. remove them these days) then it makes sense to make TMPDIR be /tmp/jove.
  341. But if you want to recover buffers on system crashes, you should create a
  342. directory that doesn't get cleared upon reboot, and use that instead.
  343. You would probably want to clean out that directory periodically with
  344. X/etc/cron.
  345. X
  346. For the pdp11 version there is the Ovmakefile.  This has only been tested
  347. on 2.9bsd.  It works pretty well, actually, and it is possible to turn on
  348. all the compile time options with this version.
  349. X
  350. Bug reports:  If you find bugs in JOVE I would appreciate hearing about
  351. them.  (My net address is at end of this message.)  So, send me the bug
  352. reports.  If the bug isn't already fixed, I will ask you to send me the
  353. fix.  If you haven't found the bug, I may be able to, so don't wait until
  354. you have found it.  If you make improvements to JOVE and want them
  355. incorporated into the official version, send me a message explaining what
  356. the change is, and I will decide whether I want to include it.  If it is
  357. possible for your change to be #ifdef'd in, that would be best, since I
  358. want to avoid making JOVE huge.  For instance, if it's a new package type
  359. thing (say, like word abbrev. mode, or something) then it would be best
  360. if that were a compile-time option.  I will send out periodic updates to
  361. mod.sources.  I will report all significant bug fixes there, and to
  362. net.emacs as well.
  363. X
  364. Here's a list of the compile time options and what they mean:
  365. X
  366. ABBREV       - Enables word-abbrev-mode which again is nice for paper writers.
  367. X
  368. BACKUPFILES - This enables backing up files on write.  I guess lots of
  369. X          people like this feature.  It enables the feature but you
  370. X          can still control whether files are backed up with the
  371. X          make-backup-files variable.
  372. X
  373. BIFF       - This enables turning on and off BIFF so your screen doesn't
  374. X          get messed up with messages from BIFF.
  375. X
  376. BSD4_2     - Obviously, if you're a Berkeley 4.2 system.
  377. X
  378. BSD4_3       - If you're running a Berkeley 4.3 or 2.10 system.
  379. X         This will automatically define BSD4_2, also.
  380. X
  381. CHDIR       - This enables the directory commands; PUSHD, POPD, DIRS and
  382. X          CD.  These simulate the csh commands exactly, I think.  As
  383. X          a side-effect, absolute path names are enabled, which means
  384. X          JOVE parses file names for "." and ".." and all that to get
  385. X          at what you REALLY mean.  It's nicer when this is enabled,
  386. X          but not essential.
  387. X
  388. CMT_FMT       - This enables code to format and indent C comments.
  389. X
  390. ID_CHAR       - Enables support for Insert/Delete character on terminals
  391. X         that have those capabilities.  Couple of problems with this code:
  392. X         it's large, takes up lots of I space which is a problem for the
  393. X         smaller computers (pdp11).  Also, it isn't particularly smart
  394. X         and sometimes does really stupid things.  It sometimes uses
  395. X         insert/delete character when simply redrawing would have been
  396. X         faster.  And if you look at code you'll understand why I don't
  397. X         like it all that much.
  398. X
  399. IPROCS       - Nice feature which lets you run interactive UNIX commands in
  400. X         windows.  In particular, there is a shell command built
  401. X         in which starts up an interactive shell in a window.  This works
  402. X         only on systems with JOB_CONTROL since it relies on the fancy
  403. X         signal mechanism.
  404. X
  405. JOB_CONTROL - Versions of UNIX that have the job control facility.
  406. X          Berkeley 2.9-10 systems, and the 4.1-3 systems I know have
  407. X          job stopping, so if you're one of those, define
  408. X          this.  The reason MENLO_JCL is defined when JOB_CONTROL
  409. X          is that the 2.9 signal.h file only defines all of the job
  410. X          stopping signals only when MENLO_JCL is defined.
  411. X
  412. LISP       - Enables Lisp Mode.  This includes code to indent "properly"
  413. X         for Lisp code and new routines to move over s-expressions.
  414. X         You probably won't want (or need) this on PDP-11's.
  415. X
  416. MY_MALLOC  - Use the older version of malloc that is more memory efficient
  417. X         than the newer 4BSD version.  The 4BSD version places more
  418. X         importance on the speed of the allocation than the amount of
  419. X         memory it uses.  Make your    choice ... JOVE hardly ever calls
  420. X         malloc, anyway, relatively speaking, since it allocates
  421. X         lines in big chunks.  NOTE: This doesn't seem to work on suns
  422. X         and the iAPX286.
  423. X
  424. PIPEPROCS  - If NOT defined, JOVE will use Berkeley pseudo-ttys when
  425. X         doing interactive processes.  This is infinitely better,
  426. X         since you get job control and all that stuff on i-procs.
  427. X         If defined, the portsrv program will have to be made, and
  428. X         all communication between jove and i-procs will be done using
  429. X         pipes.
  430. X
  431. RESHAPING  - This is for BRL or Berkeley 4.3 and 2.10 systems.  When the
  432. X         window size of the terminal jove is running in is changed
  433. X         a SIGWINCH is sent to all processes in the tty group.  This
  434. X         define enables code in jove to catch that signal and reshape
  435. X         its windows.
  436. X
  437. SPELL       - Enables the spell-buffer and parse-spelling-errors commands.
  438. X         They are nice especially if you have lots of paper writers.
  439. X
  440. WIRED_TERMS - Include compiled-in hard-wired code for certain terminals,
  441. X         like the Concept 100.  If you don't have these terminals,
  442. X         you probably don't need this (but no point in taking it
  443. X         out unless you're low on space).
  444. X
  445. The macros have been rewritten from scratch.  The most noteable change is
  446. that they are no longer stored in binary files.  The write-macros-to-file
  447. command writes a file which is suitable for use with the source command.
  448. So you can have actual macro definitions in your .joverc if you want.  If
  449. you have lots of macros defined in the old format, you can use the
  450. macvert program to convert them to the new style.  You say
  451. X    macvert old-style-macros-file > new-style-macro-file
  452. X
  453. X"doc/system.rc" and "doc/example.rc" are jove initialization files.
  454. X"system.rc" is the "system" rc file here at UoR, and it gets ready every
  455. time JOVE starts up FOR EVERYONE.  ("make install" should copy the
  456. system-wide .joverc to the right place automatically.)  After that JOVE
  457. reads an initialization file in the user's home directory.  "example.rc"
  458. is my personal .joverc.
  459. X
  460. The files "jove.[12345]" in DOC are the official JOVE manual.  I got
  461. permission from Richard Stallman to use his manual for the original EMACS,
  462. modifying it where necessary for JOVE.  Lots of work was done by Brian
  463. Harvey on this manual.
  464. X
  465. There are man pages for jove and teachjove.  Teachjove is for people who
  466. have never used EMACS style editors.  It is an interactive tutorial, THE
  467. tutorial written by Stallman for the original EMACS, only slightly
  468. modified for JOVE in the appropriate places.  The man pages are
  469. completely up to date, thanks to me.
  470. X
  471. Thanks to Jay (hack) Fenlason for writing the original pty code.
  472. X
  473. Thanks to Dave Curry at Purdue for putting in tons of time and effort
  474. into getting JOVE ready.  It just wouldn't be working without his help.
  475. X
  476. Thanks to Jeff Mc Carrell at Berkeley for finding bugs and adding
  477. features, in particular, the comment formatter.
  478. X
  479. Thanks to Karl Gegenfurtner for making the PC version.
  480. X
  481. X(Thanks to Brian Harvey for teaching me about linked lists ...)
  482. X
  483. Good luck, have fun.
  484. X
  485. X    Jonathan Payne (jpayne@cs.rochester.edu until '88)
  486. END_OF_FILE
  487. if test 8923 -ne `wc -c <'./README'`; then
  488.     echo shar: \"'./README'\" unpacked with wrong size!
  489. fi
  490. # end of './README'
  491. fi
  492. if test -f './fmt.c' -a "${1}" != "-c" ; then 
  493.   echo shar: Will not clobber existing file \"'./fmt.c'\"
  494. else
  495. echo shar: Extracting \"'./fmt.c'\" \(7964 characters\)
  496. sed "s/^X//" >'./fmt.c' <<'END_OF_FILE'
  497. X/***************************************************************************
  498. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  499. X * is provided to you without charge, and with no warranty.  You may give  *
  500. X * away copies of JOVE, including sources, provided that this notice is    *
  501. X * included in all the files.                                              *
  502. X ***************************************************************************/
  503. X
  504. X#include "jove.h"
  505. X#include "io.h"
  506. X#include "termcap.h"
  507. X
  508. X#ifdef MAC
  509. X#    include  "mac.h"
  510. X#else
  511. X#    include <varargs.h>
  512. X#endif
  513. X
  514. X#ifdef MAC
  515. X#    undef private
  516. X#    define private
  517. X#endif
  518. X
  519. X#ifdef    LINT_ARGS
  520. private void
  521. X    doformat(File *, char *, ...),
  522. X    outld(long, int),
  523. X    pad(int, int),
  524. X    PPchar(int, char *),
  525. X    putld(long, int),
  526. X    puts(char *);
  527. X#else
  528. private void
  529. X    doformat(),
  530. X    outld(),
  531. X    pad(),
  532. X    PPchar(),
  533. X    putld(),
  534. X    puts();
  535. X#endif    /* LINT_ARGS */
  536. X
  537. X#ifdef MAC
  538. X#    undef private
  539. X#    define private static
  540. X#endif
  541. X
  542. X
  543. char    mesgbuf[MESG_SIZE];
  544. X
  545. X/* VARARGS2 */
  546. X
  547. void
  548. format(buf, len, fmt, ap)
  549. char    *buf,
  550. X    *fmt;
  551. va_list    ap;
  552. X{
  553. X    File    strbuf,
  554. X        *sp = &strbuf;
  555. X
  556. X     sp->f_ptr = sp->f_base = buf;
  557. X    sp->f_fd = -1;        /* Not legit for files */
  558. X    sp->f_cnt = len;
  559. X    sp->f_flags = F_STRING;
  560. X    sp->f_bufsize = len;
  561. X
  562. X    doformat(sp, fmt, ap);
  563. X    putc('\0', sp);
  564. X}
  565. X
  566. X#ifdef IBMPC
  567. int    specialmap = 0,
  568. X    specialkey = 0;
  569. X
  570. X#define Empty ""
  571. X
  572. char *altseq[133] = {
  573. Empty, Empty, Empty, "Ctrl-@", Empty, Empty, Empty, Empty,
  574. Empty, Empty, Empty, Empty, Empty, Empty, Empty, "Left", 
  575. X"Alt-Q", "Alt-W", "Alt-E", "Alt-R", "Alt-T", "Alt-Y", "Alt-U", "Alt-I",
  576. X"Alt-O", "Alt-P", Empty, Empty, Empty, Empty, "Alt-A", "Alt-S",
  577. X"Alt-D", "Alt-F", "Alt-G", "Alt-H", "Alt-J", "Alt-K", "Alt-L", Empty,
  578. Empty, Empty, Empty, Empty, "Alt-Z", "Alt-X", "Alt-C", "Alt-V",
  579. X"Alt-B", "Alt-N", "Alt-M", Empty, Empty, Empty, Empty, Empty,
  580. Empty, Empty, Empty, "F1", "F2", "F3", "F4", "F5", 
  581. X"F6", "F7", "F8", "F9", "F10", Empty, Empty, "Home",
  582. X"Up", "PageUp", Empty, "Left", Empty, "Right", Empty, "End",
  583. X"Down", "PageDown", "Ins", "Del", "Shift F1", "Shift F2", "Shift F3", "Shift F4", 
  584. X"Shift F5", "Shift F6", "Shift F7", "Shift F8", "Shift F9", "Shift F10", "Ctrl F1", "Ctrl F2",
  585. X"Ctrl F3", "Ctrl F4", "Ctrl F5", "Ctrl F6", "Ctrl F7", "Ctrl F8", "Ctrl F9", "Ctrl F10", 
  586. X"Alt F1", "Alt F2", "Alt F3", "Alt F4", "Alt F5", "Alt F6", "Alt F7", "Alt F8",
  587. X"Alt F9", "Alt F10", "Ctrl PrtSc", "Ctrl Left", "Ctrl Right", "Ctrl End", "Ctrl PageDown", "Ctrl Home",
  588. X"Alt 1", "Alt 2", "Alt 3", "Alt 4", "Alt 5", "Alt 6", "Alt 7", "Alt 8",
  589. X"Alt 9", "Alt 0", "Alt Minus", "Alt Equals", "Ctrl PageUp" 
  590. X};
  591. X#endif
  592. X
  593. X
  594. private void
  595. PPchar(c, str)
  596. int    c;
  597. char    *str;
  598. X{
  599. X    char    *cp = str;
  600. X
  601. X#ifdef IBMPC
  602. X    if (specialmap || specialkey) {
  603. X        if (c < 0 || c > 132)
  604. X            c = 0;
  605. X        strcpy(cp, altseq[c]);
  606. X    } else
  607. X#endif    
  608. X    if (c == '\033')
  609. X        strcpy(cp, "ESC");
  610. X#ifdef IBMPC                /* this character is invisible */
  611. X    else if (c == '\377') {
  612. X            *cp = 0;
  613. X    }
  614. X#endif /* IBMPC */
  615. X    else if (c < ' ')
  616. X        sprintf(cp, "C-%c", c + '@');
  617. X    else if (c == '\177')
  618. X        strcpy(cp, "^?");
  619. X    else
  620. X        sprintf(cp, "%c", c);
  621. X}
  622. X
  623. private struct fmt_state {
  624. X    int    precision,
  625. X        width,
  626. X        leftadj;
  627. X    char    padc;
  628. X    File    *iop;
  629. X} current_fmt;
  630. X
  631. private void
  632. putld(d, base)
  633. long    d;
  634. X{
  635. X    int    length = 1;
  636. X    long    tmpd = d;
  637. X
  638. X    if (current_fmt.width == 0 && current_fmt.precision) {
  639. X        current_fmt.width = current_fmt.precision;
  640. X        current_fmt.padc = '0';
  641. X    }
  642. X    while (tmpd = (tmpd / base))
  643. X        length += 1;
  644. X    if (d < 0)
  645. X        length += 1;
  646. X    if (!current_fmt.leftadj)
  647. X        pad(current_fmt.padc, current_fmt.width - length);
  648. X    if (d < 0) {
  649. X        putc('-', current_fmt.iop);
  650. X        d = -d;
  651. X    }
  652. X    outld(d, base);
  653. X    if (current_fmt.leftadj)
  654. X        pad(current_fmt.padc, current_fmt.width - length);
  655. X}
  656. X
  657. private void
  658. outld(d, base)
  659. long    d;
  660. X{
  661. X    register long    n;
  662. X    static char    chars[] = {'0', '1', '2', '3', '4', '5', '6',
  663. X                    '7', '8', '9', 'a', 'b', 'c', 'd',
  664. X                    'e', 'f'};
  665. X
  666. X    if (n = (d / base))
  667. X        outld(n, base);
  668. X    putc((int) (chars[(int) (d % base)]), current_fmt.iop);
  669. X}
  670. X
  671. private void
  672. puts(str)
  673. char    *str;
  674. X{
  675. X    int    length;
  676. X    register char    *cp;
  677. X
  678. X    if (str == 0)
  679. X#if pyr
  680. X        str = "";
  681. X#else
  682. X        str = "(null)";
  683. X#endif
  684. X    length = strlen(str);
  685. X    if (current_fmt.precision == 0 || length < current_fmt.precision)
  686. X        current_fmt.precision = length;
  687. X    else
  688. X        length = current_fmt.precision;
  689. X    cp = str;
  690. X    if (!current_fmt.leftadj)
  691. X        pad(' ', current_fmt.width - length);
  692. X    while (--current_fmt.precision >= 0)
  693. X        putc(*cp++, current_fmt.iop);
  694. X    if (current_fmt.leftadj)
  695. X        pad(' ', current_fmt.width - length);
  696. X}
  697. X
  698. private void
  699. pad(c, amount)
  700. register int    c,
  701. X        amount;
  702. X{
  703. X    while (--amount >= 0)
  704. X        putc(c, current_fmt.iop);
  705. X}
  706. X
  707. private void
  708. doformat(sp, fmt, ap)
  709. register File    *sp;
  710. register char    *fmt;
  711. va_list    ap;
  712. X{
  713. X    register char    c;
  714. X    struct fmt_state    prev_fmt;
  715. X
  716. X    prev_fmt = current_fmt;
  717. X    current_fmt.iop = sp;
  718. X
  719. X    while (c = *fmt++) {
  720. X        if (c != '%') {
  721. X            putc(c, current_fmt.iop);
  722. X            continue;
  723. X        }
  724. X
  725. X        current_fmt.padc = ' ';
  726. X        current_fmt.precision = current_fmt.leftadj = current_fmt.width = 0;
  727. X        c = *fmt++;
  728. X        if (c == '-') {
  729. X            current_fmt.leftadj = YES;
  730. X            c = *fmt++;
  731. X        }
  732. X        if (c == '0') {
  733. X            current_fmt.padc = '0';
  734. X            c = *fmt++;
  735. X        }
  736. X        while (c >= '0' && c <= '9') {
  737. X            current_fmt.width = current_fmt.width * 10 + (c - '0');
  738. X            c = *fmt++;
  739. X        }
  740. X        if (c == '*') {
  741. X            current_fmt.width = va_arg(ap, int);
  742. X            c = *fmt++;
  743. X        }
  744. X        if (c == '.') {
  745. X            c = *fmt++;
  746. X            while (c >= '0' && c <= '9') {
  747. X                current_fmt.precision = current_fmt.precision * 10 + (c - '0');
  748. X                c = *fmt++;
  749. X            }
  750. X            if (c == '*') {
  751. X                current_fmt.precision = va_arg(ap, int);
  752. X                c = *fmt++;
  753. X            }
  754. X        }
  755. X    reswitch:
  756. X        /* At this point, fmt points at one past the format letter. */
  757. X        switch (c) {
  758. X        case '%':
  759. X            putc('%', current_fmt.iop);
  760. X            break;
  761. X    
  762. X        case 'O':
  763. X        case 'D':
  764. X        case 'X':
  765. X            putld(va_arg(ap, long), (c == 'O') ? 8 :
  766. X                        (c == 'D') ? 10 : 16);
  767. X            break;
  768. X    
  769. X        case 'b':
  770. X            {
  771. X            Buffer    *b = va_arg(ap, Buffer *);
  772. X
  773. X            puts(b->b_name);
  774. X            break;
  775. X            }
  776. X
  777. X        case 'c':
  778. X            putc(va_arg(ap, int), current_fmt.iop);
  779. X            break;
  780. X    
  781. X        case 'o':
  782. X        case 'd':
  783. X        case 'x':
  784. X            putld((long) va_arg(ap, int), (c == 'o') ? 8 :
  785. X                        (c == 'd') ? 10 : 16);
  786. X            break;
  787. X    
  788. X        case 'f':    /* current command name gets inserted here! */
  789. X            puts(LastCmd->Name);
  790. X            break;
  791. X
  792. X        case 'l':
  793. X            c = CharUpcase(*++fmt);
  794. X            goto reswitch;
  795. X    
  796. X        case 'n':
  797. X            if (va_arg(ap, int) != 1)
  798. X                puts("s");
  799. X            break;
  800. X
  801. X        case 'p':
  802. X            {
  803. X                char    cbuf[20];
  804. X
  805. X                PPchar(va_arg(ap, int), cbuf);
  806. X                puts(cbuf);
  807. X                break;
  808. X            }
  809. X
  810. X        case 's':
  811. X            puts(va_arg(ap, char *));
  812. X            break;
  813. X        
  814. X        default:
  815. X            complain("Unknown format directive: \"%%%c\"", c);
  816. X        }
  817. X    }
  818. X    current_fmt = prev_fmt;
  819. X}
  820. X
  821. X/* VARARGS1 */
  822. X
  823. char *
  824. sprint(fmt, va_alist)
  825. char    *fmt;
  826. va_dcl
  827. X{
  828. X    va_list    ap;
  829. X    static char    line[100];
  830. X
  831. X    va_start(ap);
  832. X    format(line, sizeof line, fmt, ap);
  833. X    va_end(ap);
  834. X    return line;
  835. X}
  836. X
  837. X/* VARARGS1 */
  838. X
  839. void
  840. printf(fmt, va_alist)
  841. char    *fmt;
  842. va_dcl
  843. X{
  844. X    va_list    ap;
  845. X
  846. X    va_start(ap);
  847. X#ifndef IBMPC
  848. X    doformat(stdout, fmt, ap);
  849. X#else /* IBMPC */
  850. X    write_em(sprint(fmt, ap));
  851. X    /* doformat(stdout, fmt, ap); */
  852. X#endif /* IBMPC */
  853. X    va_end(ap);
  854. X}
  855. X
  856. X/* VARARGS1 */
  857. X
  858. void
  859. fprintf(fp, fmt, va_alist)
  860. File    *fp;
  861. char    *fmt;
  862. va_dcl
  863. X{
  864. X    va_list    ap;
  865. X
  866. X    va_start(ap);
  867. X    doformat(fp, fmt, ap);
  868. X    va_end(ap);
  869. X}
  870. X
  871. X/* VARARGS2 */
  872. X
  873. void
  874. sprintf(str, fmt, va_alist)
  875. char    *str,
  876. X    *fmt;
  877. va_dcl
  878. X{
  879. X    va_list    ap;
  880. X
  881. X    va_start(ap);
  882. X    format(str, 130, fmt, ap);
  883. X    va_end(ap);
  884. X}
  885. X
  886. X/* VARARGS1 */
  887. X
  888. void
  889. s_mess(fmt, va_alist)
  890. char    *fmt;
  891. va_dcl
  892. X{
  893. X    va_list    ap;
  894. X
  895. X    if (InJoverc)
  896. X        return;
  897. X    va_start(ap);
  898. X    format(mesgbuf, sizeof mesgbuf, fmt, ap);
  899. X    va_end(ap);
  900. X    message(mesgbuf);
  901. X}
  902. X
  903. X/* VARARGS1 */
  904. X
  905. void
  906. f_mess(fmt, va_alist)
  907. char    *fmt;
  908. va_dcl
  909. X{
  910. X    va_list    ap;
  911. X
  912. X    va_start(ap);
  913. X    format(mesgbuf, sizeof mesgbuf, fmt, ap);
  914. X    va_end(ap);
  915. X    DrawMesg(NO);
  916. X    UpdMesg = YES;    /* still needs updating (for convenience) */
  917. X}
  918. X
  919. X/* VARARGS1 */
  920. X
  921. void
  922. add_mess(fmt, va_alist)
  923. char    *fmt;
  924. va_dcl
  925. X{
  926. X    int    mesg_len = strlen(mesgbuf);
  927. X    va_list    ap;
  928. X
  929. X    if (InJoverc)
  930. X        return;
  931. X    va_start(ap);
  932. X    format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap);
  933. X    va_end(ap);
  934. X    message(mesgbuf);
  935. X}
  936. END_OF_FILE
  937. if test 7964 -ne `wc -c <'./fmt.c'`; then
  938.     echo shar: \"'./fmt.c'\" unpacked with wrong size!
  939. fi
  940. # end of './fmt.c'
  941. fi
  942. if test -f './iproc.c' -a "${1}" != "-c" ; then 
  943.   echo shar: Will not clobber existing file \"'./iproc.c'\"
  944. else
  945. echo shar: Extracting \"'./iproc.c'\" \(9262 characters\)
  946. sed "s/^X//" >'./iproc.c' <<'END_OF_FILE'
  947. X/***************************************************************************
  948. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  949. X * is provided to you without charge, and with no warranty.  You may give  *
  950. X * away copies of JOVE, including sources, provided that this notice is    *
  951. X * included in all the files.                                              *
  952. X ***************************************************************************/
  953. X
  954. X#include "jove.h"
  955. X#include "re.h"
  956. X#include <varargs.h>
  957. X
  958. X#ifdef IPROCS
  959. X
  960. int    proc_child();
  961. X
  962. X#ifdef PIPEPROCS
  963. X#   include "iproc-pipes.c"
  964. X#else
  965. X#   include "iproc-ptys.c"
  966. X#endif
  967. X
  968. char    proc_prompt[128] = "% ";
  969. X
  970. KillProcs()
  971. X{
  972. X    register Process    *p;
  973. X    register int    killem = -1;        /* -1 means undetermined */
  974. X    register char    *yorn;
  975. X
  976. X    for (p = procs; p != 0; p = p->p_next)
  977. X        if (!isdead(p)) {
  978. X            if (killem == -1) {
  979. X                yorn = ask("y", "Should I kill your i-processes? ");
  980. X                killem = (CharUpcase(*yorn) == 'Y');
  981. X            }
  982. X            if (killem)
  983. X                proc_kill(p, SIGKILL);
  984. X        }
  985. X}
  986. X
  987. pbuftiedp(b)
  988. register Buffer    *b;
  989. X{
  990. X    register Process    *p = b->b_process;
  991. X
  992. X    if (!isdead(p))
  993. X        complain("Process %s, attached to %b, is %s.",
  994. X             proc_cmd(p), b, pstate(p));
  995. X}
  996. X
  997. X/* Process receive: receives the characters in buf, and appends them to
  998. X   the buffer associated with p. */
  999. X
  1000. private
  1001. proc_rec(p, buf)
  1002. register Process    *p;
  1003. char    *buf;
  1004. X{
  1005. X    Buffer    *saveb = curbuf;
  1006. X    register Window    *w;
  1007. X    register Mark    *savepoint;
  1008. X    int    sameplace = NO,
  1009. X        do_disp = NO;
  1010. X
  1011. X    if (curwind->w_bufp == p->p_buffer)
  1012. X        w = curwind;
  1013. X    else
  1014. X        w = windbp(p->p_buffer);    /* Is this window visible? */
  1015. X    if (w != 0)
  1016. X        do_disp = (in_window(w, p->p_mark->m_line) != -1);
  1017. X    SetBuf(p->p_buffer);
  1018. X    savepoint = MakeMark(curline, curchar, M_FLOATER);
  1019. X    ToMark(p->p_mark);        /* where output last stopped */
  1020. X    if (savepoint->m_line == curline && savepoint->m_char == curchar)
  1021. X        sameplace = YES;
  1022. X
  1023. X    ins_str(buf, YES);
  1024. X    MarkSet(p->p_mark, curline, curchar);
  1025. X    if (!sameplace)
  1026. X        ToMark(savepoint);    /* back to where we were */
  1027. X    DelMark(savepoint);
  1028. X    /* redisplay now, instead of right after the ins_str, so that
  1029. X       we don't get a bouncing effect if point is not the same as
  1030. X       the process output position */
  1031. X    if (do_disp) {
  1032. X        w->w_line = curline;
  1033. X        w->w_char = curchar;
  1034. X        redisplay();
  1035. X    }
  1036. X    SetBuf(saveb);
  1037. X}
  1038. X
  1039. proc_kill(p, sig)
  1040. register Process    *p;
  1041. X{
  1042. X    if (isdead(p))
  1043. X        return;
  1044. X    if (killpg(p->p_pid, sig) == -1)
  1045. X        s_mess("Cannot kill %s!", proc_buf(p));
  1046. X}
  1047. X
  1048. X/* Free process CHILD.  Do all the necessary cleaning up (closing fd's,
  1049. X   etc.). */
  1050. X
  1051. free_proc(child)
  1052. Process    *child;
  1053. X{
  1054. X    register Process    *p,
  1055. X                *prev = 0;
  1056. X
  1057. X    if (!isdead(child))
  1058. X        return;    
  1059. X    for (p = procs; p != child; prev = p, p = p->p_next)
  1060. X        ;
  1061. X    if (prev == 0)
  1062. X        procs = child->p_next;
  1063. X    else
  1064. X        prev->p_next = child->p_next;
  1065. X    proc_close(child);        /* if not already closed */
  1066. X    
  1067. X    /* It's possible that the buffer has been given another process
  1068. X       between the time CHILD dies and CHILD's death is noticed (via
  1069. X       list-processes).  So we only set it the buffer's process to
  1070. X       0 if CHILD is still the controlling process. */
  1071. X    if (child->p_buffer->b_process == child) {
  1072. X        child->p_buffer->b_process = 0;
  1073. X        if (curbuf == child->p_buffer)
  1074. X            PopPBs();
  1075. X    }
  1076. X    {
  1077. X        Buffer    *old = curbuf;
  1078. X
  1079. X        SetBuf(child->p_buffer);
  1080. X        DelMark(child->p_mark);
  1081. X        SetBuf(old);
  1082. X    }
  1083. X    free((char *) child->p_name);
  1084. X    free((char *) child);
  1085. X}
  1086. X
  1087. ProcList()
  1088. X{
  1089. X    register Process    *p,
  1090. X                *next;
  1091. X    char    *fmt = "%-15s  %-15s  %-8s %s",
  1092. X        pidstr[16];
  1093. X
  1094. X    if (procs == 0) {
  1095. X        message("[No subprocesses]");
  1096. X        return;
  1097. X    }
  1098. X    TOstart("Process list", TRUE);
  1099. X
  1100. X    Typeout(fmt, "Buffer", "Status", "Pid ", "Command");
  1101. X    Typeout(fmt, "------", "------", "--- ", "-------");
  1102. X    for (p = procs; p != 0; p = next) {
  1103. X        next = p->p_next;
  1104. X        sprintf(pidstr, "%d", p->p_pid);
  1105. X        Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name);
  1106. X        if (isdead(p)) {
  1107. X            free_proc(p);
  1108. X            UpdModLine = YES;
  1109. X        }
  1110. X    }
  1111. X    TOstop();
  1112. X}
  1113. X
  1114. ProcNewline()
  1115. X{
  1116. X#ifdef ABBREV
  1117. X    MaybeAbbrevExpand();
  1118. X#endif
  1119. X    SendData(YES);
  1120. X}
  1121. X
  1122. ProcSendData()
  1123. X{
  1124. X#ifdef ABBREV
  1125. X    MaybeAbbrevExpand();
  1126. X#endif
  1127. X    SendData(NO);
  1128. X}
  1129. X
  1130. private
  1131. SendData(newlinep)
  1132. X{
  1133. X    register Process    *p = curbuf->b_process;
  1134. X    register char    *lp,
  1135. X            *gp;    /* JF fix for better prompt handling */
  1136. X
  1137. X    if (isdead(p))
  1138. X        return;
  1139. X    /* If the process mark was involved in a big deletion, because
  1140. X       the user hit ^W or something, then let's do some magic with
  1141. X       the process mark.  Problem is that if the user yanks back the
  1142. X       text he deleted, the mark stays at the beginning of the region,
  1143. X       and so the next time SendData() is called the entire region
  1144. X       will be sent.  That's not good.  So, to deal with that we reset
  1145. X       the mark to the last line, after skipping over the prompt, etc. */
  1146. X    if (p->p_mark->m_flags & M_BIG_DELETE) {
  1147. X        Bufpos    bp;
  1148. X
  1149. X        p->p_mark->m_flags &= ~M_BIG_DELETE;
  1150. X
  1151. X        DOTsave(&bp);
  1152. X        ToLast();
  1153. X        Bol();
  1154. X        /* While we're looking at a prompt, and while we're
  1155. X           moving forward.  This is for people who accidently
  1156. X           set their process-prompt to ">*" which will always
  1157. X           match! */
  1158. X        while ((LookingAt(proc_prompt, linebuf, curchar)) &&
  1159. X                (REeom > curchar))
  1160. X            curchar = REeom;
  1161. X        MarkSet(p->p_mark, curline, curchar);
  1162. X        SetDot(&bp);
  1163. X    }
  1164. X
  1165. X    if (lastp(curline)) {
  1166. X        Eol();
  1167. X        if (newlinep)
  1168. X            LineInsert(1);
  1169. X        do_rtp(p->p_mark);
  1170. X        MarkSet(p->p_mark, curline, curchar);
  1171. X    } else {
  1172. X        /* Either we're looking at a prompt, or we're not, in
  1173. X           which case we want to strip off the beginning of the
  1174. X           line anything that looks like what the prompt at the
  1175. X           end of the file is.  In other words, if "(dbx) stop in
  1176. X           ProcessNewline" is the line we're on, and the last
  1177. X           line in the buffer is "(dbx) ", then we strip off the
  1178. X           leading "(dbx) " from this line, because we know it's
  1179. X           part of the prompt.  But this only happens if "(dbx) "
  1180. X           isn't one of the process prompts ... follow what I'm
  1181. X           saying? */
  1182. X        Bol();
  1183. X        if (LookingAt(proc_prompt, linebuf, curchar)) {
  1184. X            do
  1185. X                curchar = REeom;
  1186. X            while ((LookingAt(proc_prompt, linebuf, curchar)) &&
  1187. X                   (REeom > curchar));
  1188. X            strcpy(genbuf, linebuf + curchar);
  1189. X            Eof();
  1190. X            ins_str(genbuf, NO);
  1191. X        } else {
  1192. X            strcpy(genbuf, linebuf + curchar);
  1193. X            Eof();
  1194. X            gp = genbuf;
  1195. X            lp = linebuf;
  1196. X            while (*lp == *gp && *lp != '\0') {
  1197. X                lp += 1;
  1198. X                gp += 1;
  1199. X            }
  1200. X            ins_str(gp, NO);
  1201. X        }
  1202. X    }
  1203. X}
  1204. X
  1205. ShellProc()
  1206. X{
  1207. X    char    *shbuf = "*shell*";
  1208. X    register Buffer    *b;
  1209. X
  1210. X    b = buf_exists(shbuf);
  1211. X    if (b == 0 || isdead(b->b_process))
  1212. X        proc_strt(shbuf, NO, Shell, "-i", (char *) 0);
  1213. X    pop_wind(shbuf, NO, -1);
  1214. X}
  1215. X
  1216. Iprocess()
  1217. X{
  1218. X    extern char    ShcomBuf[100],
  1219. X            *MakeName();
  1220. X    register char    *command;
  1221. X    char    scratch[64],
  1222. X        *bufname;
  1223. X    int    cnt = 1;
  1224. X    Buffer    *bp;
  1225. X
  1226. X    command = ask(ShcomBuf, ProcFmt);
  1227. X    null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1);
  1228. X    bufname = MakeName(command);
  1229. X    strcpy(scratch, bufname);
  1230. X    while ((bp = buf_exists(scratch)) && !isdead(bp->b_process))
  1231. X        sprintf(scratch, "%s.%d", bufname, cnt++);
  1232. X    proc_strt(scratch, YES, Shell, ShFlags, command, (char *) 0);
  1233. X}
  1234. X
  1235. proc_child()
  1236. X{
  1237. X    union wait    w;
  1238. X    register int    pid;
  1239. X
  1240. X    for (;;) {
  1241. X#ifndef BSD4_2
  1242. X        pid = wait2(&w.w_status, (WNOHANG | WUNTRACED));
  1243. X#else
  1244. X        pid = wait3(&w, (WNOHANG | WUNTRACED), (struct rusage *) 0);
  1245. X#endif
  1246. X        if (pid <= 0)
  1247. X            break;
  1248. X        kill_off(pid, w);
  1249. X    }
  1250. X}
  1251. X
  1252. kill_off(pid, w)
  1253. register int    pid;
  1254. union wait    w;
  1255. X{
  1256. X    register Process    *child;
  1257. X
  1258. X    if ((child = proc_pid(pid)) == 0)
  1259. X        return;
  1260. X
  1261. X    UpdModLine = YES;        /* we're changing state ... */
  1262. X    if (WIFSTOPPED(w))
  1263. X        child->p_state = STOPPED;
  1264. X    else {
  1265. X        child->p_state = DEAD;
  1266. X        if (WIFEXITED(w))
  1267. X            child->p_howdied = EXITED;
  1268. X        else if (WIFSIGNALED(w)) {
  1269. X            child->p_reason = w.w_termsig;
  1270. X            child->p_howdied = KILLED;
  1271. X        }
  1272. X        {
  1273. X            Buffer    *save = curbuf;
  1274. X            char    mesg[128];
  1275. X
  1276. X            /* insert status message now */
  1277. X            sprintf(mesg, "[Process %s: %s]\n",
  1278. X                proc_cmd(child),
  1279. X                pstate(child));
  1280. X            SetBuf(child->p_buffer);
  1281. X            ins_str(mesg, NO);
  1282. X            SetBuf(save);
  1283. X            redisplay();
  1284. X        }
  1285. X    }
  1286. X}
  1287. X
  1288. X/* Push/pod process bindings.  I openly acknowledge that this is a
  1289. X   kludge, but I can't be bothered making it right. */
  1290. X
  1291. struct proc_bind {
  1292. X    int        pb_key;
  1293. X    data_obj    **pb_map;
  1294. X    data_obj    *pb_push;
  1295. X    data_obj    *pb_cmd;
  1296. X    struct proc_bind *pb_next;
  1297. X};
  1298. X
  1299. struct proc_bind *PBinds = 0;
  1300. X
  1301. PopPBs()
  1302. X{
  1303. X    register struct proc_bind *p;
  1304. X
  1305. X    for (p = PBinds; p != 0; p = p->pb_next)
  1306. X        p->pb_map[p->pb_key] = p->pb_push;
  1307. X}
  1308. X
  1309. PushPBs()
  1310. X{
  1311. X    register struct proc_bind *p;
  1312. X
  1313. X    for (p = PBinds; p != 0; p = p->pb_next) {
  1314. X        p->pb_push = p->pb_map[p->pb_key];
  1315. X        p->pb_map[p->pb_key] = p->pb_cmd;
  1316. X    }
  1317. X}
  1318. X/* VARARGS0 */
  1319. X
  1320. ProcBind()
  1321. X{
  1322. X    register data_obj    *d;
  1323. X
  1324. X    if ((d = findcom(ProcFmt)) == 0)
  1325. X        return;
  1326. X    s_mess(": %f %s ", d->Name);
  1327. X    ProcB2(mainmap, EOF, d);
  1328. X}
  1329. X
  1330. ProcB2(map, lastkey, cmd)
  1331. data_obj    **map,
  1332. X        *cmd;
  1333. X{
  1334. X    register struct proc_bind *p;
  1335. X    register data_obj    **nextmap;
  1336. X    int    c;
  1337. X
  1338. X    c = addgetc();
  1339. X    if (c == EOF) {
  1340. X        if (lastkey == EOF)
  1341. X            complain("[Empty key sequence]");
  1342. X        complain("[Unexpected end-of-line]");
  1343. X    } else {
  1344. X        if (nextmap = IsPrefix(map[c]))
  1345. X            ProcB2(nextmap, c, cmd);
  1346. X        else {
  1347. X            if (curbuf->b_process)
  1348. X                PopPBs();
  1349. X
  1350. X            for (p = PBinds; p != 0; p = p->pb_next)
  1351. X                if (p->pb_key == c && p->pb_map == map)
  1352. X                    break;
  1353. X            if (p == 0) {
  1354. X                p = (struct proc_bind *) emalloc(sizeof *p);
  1355. X                p->pb_next = PBinds;
  1356. X                PBinds = p;
  1357. X            }
  1358. X            p->pb_map = map;
  1359. X            p->pb_key = c;
  1360. X            p->pb_cmd = cmd;
  1361. X
  1362. X            if (curbuf->b_process)
  1363. X                PushPBs();
  1364. X        }
  1365. X    }
  1366. X}
  1367. X
  1368. X#endif /* IPROCS */
  1369. X
  1370. END_OF_FILE
  1371. if test 9262 -ne `wc -c <'./iproc.c'`; then
  1372.     echo shar: \"'./iproc.c'\" unpacked with wrong size!
  1373. fi
  1374. # end of './iproc.c'
  1375. fi
  1376. if test -f './misc.c' -a "${1}" != "-c" ; then 
  1377.   echo shar: Will not clobber existing file \"'./misc.c'\"
  1378. else
  1379. echo shar: Extracting \"'./misc.c'\" \(7989 characters\)
  1380. sed "s/^X//" >'./misc.c' <<'END_OF_FILE'
  1381. X/***************************************************************************
  1382. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  1383. X * is provided to you without charge, and with no warranty.  You may give  *
  1384. X * away copies of JOVE, including sources, provided that this notice is    *
  1385. X * included in all the files.                                              *
  1386. X ***************************************************************************/
  1387. X
  1388. X#include "jove.h"
  1389. X#include "ctype.h"
  1390. X#include <signal.h>
  1391. X#ifdef ANSICODES
  1392. X#include "termcap.h"
  1393. X#endif
  1394. X
  1395. void
  1396. prCTIME()
  1397. X{
  1398. X    s_mess(": %f %s", get_time((time_t *) 0, (char *) 0, 0, -1));
  1399. X}
  1400. X
  1401. void
  1402. ChrToOct()
  1403. X{
  1404. X    int    c,
  1405. X        slow;
  1406. X
  1407. X    c = waitchar(&slow);
  1408. X    if (slow)
  1409. X        message(key_strokes);
  1410. X    ins_str(sprint("\\%03o", c), NO);
  1411. X}
  1412. X
  1413. void
  1414. StrLength()
  1415. X{
  1416. X    static char    inquotes[] = "Where are the quotes?";
  1417. X    char    *first = StrIndex(-1, linebuf, curchar, '"'),
  1418. X        *last = StrIndex(1, linebuf, curchar + 1, '"'),
  1419. X        c;
  1420. X    int    numchars = 0;
  1421. X
  1422. X    if (first == 0 || last == 0)
  1423. X        complain(inquotes);
  1424. X    first += 1;
  1425. X    while (first < last) {
  1426. X        c = *first++;
  1427. X        if (c == '\\') {
  1428. X            int    num;
  1429. X
  1430. X            if (!isdigit(*first))
  1431. X                first += 1;
  1432. X            else {
  1433. X                num = 3;
  1434. X                while (num-- && isdigit(*first++) && first < last)
  1435. X                    ;
  1436. X            }
  1437. X        }
  1438. X        numchars += 1;
  1439. X    }
  1440. X    s_mess("%d characters", numchars);
  1441. X}
  1442. X
  1443. X/* Transpos cur_char with cur_char - 1 */
  1444. X
  1445. void
  1446. TransChar()
  1447. X{
  1448. X    char    before;
  1449. X
  1450. X    if (curchar == 0 || (eolp() && curchar == 1))
  1451. X        complain((char *) 0);    /* BEEP */
  1452. X    if (eolp())
  1453. X        b_char(1);
  1454. X    before = linebuf[curchar - 1];
  1455. X    del_char(BACKWARD, 1);
  1456. X    f_char(1);
  1457. X    insert_c(before, 1);
  1458. X}
  1459. X
  1460. X/* Switch current line with previous one */
  1461. X
  1462. void
  1463. TransLines()
  1464. X{
  1465. X    disk_line    old_prev;
  1466. X
  1467. X    if (firstp(curline))
  1468. X        return;
  1469. X    lsave();
  1470. X    old_prev = curline->l_prev->l_dline;
  1471. X    curline->l_prev->l_dline = curline->l_dline;
  1472. X    curline->l_dline = old_prev;
  1473. X    getDOT();
  1474. X    if (!lastp(curline))
  1475. X        line_move(FORWARD, 1, NO);
  1476. X    modify();
  1477. X}
  1478. X
  1479. void
  1480. Leave()
  1481. X{
  1482. X    longjmp(mainjmp, QUIT);
  1483. X}
  1484. X
  1485. X/* If argument is specified, kill that many lines down.  Otherwise,
  1486. X   if we "appear" to be at the end of a line, i.e. everything to the
  1487. X   right of the cursor is white space, we delete the line separator
  1488. X   as if we were at the end of the line. */
  1489. X
  1490. void
  1491. KillEOL()
  1492. X{
  1493. X    Line    *line2;
  1494. X    int    char2;
  1495. X    int    num = arg_value();
  1496. X
  1497. X    if (is_an_arg()) {
  1498. X        if (num == 0) {    /* Kill to beginning of line */
  1499. X            line2 = curline;
  1500. X            char2 = 0;
  1501. X        } else {
  1502. X            line2 = next_line(curline, num);
  1503. X            if ((LineDist(curline, line2) < num) || (line2 == curline))
  1504. X                char2 = length(line2);
  1505. X            else
  1506. X                char2 = 0;
  1507. X        }
  1508. X    } else if (blnkp(&linebuf[curchar])) {
  1509. X        line2 = next_line(curline, 1);
  1510. X        if (line2 == curline)
  1511. X            char2 = length(curline);
  1512. X        else
  1513. X            char2 = 0;
  1514. X    } else {
  1515. X        line2 = curline;
  1516. X        char2 = length(curline);
  1517. X    }
  1518. X    reg_kill(line2, char2, 0);
  1519. X}
  1520. X
  1521. X/* kill to beginning of sentence */
  1522. X
  1523. void
  1524. KillBos()
  1525. X{
  1526. X    negate_arg_value();
  1527. X    KillEos();
  1528. X}
  1529. X
  1530. X/* Kill to end of sentence */
  1531. X
  1532. void
  1533. KillEos()
  1534. X{
  1535. X    Line    *line1;
  1536. X    int    char1;
  1537. X
  1538. X    line1 = curline;
  1539. X    char1 = curchar;
  1540. X    Eos();
  1541. X    reg_kill(line1, char1, 1);
  1542. X}
  1543. X
  1544. void
  1545. KillExpr()
  1546. X{
  1547. X    Line    *line1;
  1548. X    int    char1;
  1549. X
  1550. X    line1 = curline;
  1551. X    char1 = curchar;
  1552. X    FSexpr();
  1553. X    reg_kill(line1, char1, 1);
  1554. X}
  1555. X
  1556. void
  1557. EscPrefix()
  1558. X{
  1559. X    HandlePref(pref1map);
  1560. X}
  1561. X
  1562. void
  1563. CtlxPrefix()
  1564. X{
  1565. X    HandlePref(pref2map);
  1566. X}
  1567. X
  1568. void
  1569. MiscPrefix()
  1570. X{
  1571. X    HandlePref(miscmap);
  1572. X}
  1573. X
  1574. void
  1575. HandlePref(map)
  1576. data_obj    **map;
  1577. X{
  1578. X    register data_obj    *cp;
  1579. X    register int    c;
  1580. X    int    slow;
  1581. X
  1582. X    c = waitchar(&slow);
  1583. X    if (c == AbortChar) {
  1584. X        message("[Aborted]");
  1585. X        rbell();
  1586. X        return;
  1587. X    }
  1588. X
  1589. X    if (slow)
  1590. X        message(key_strokes);
  1591. X
  1592. X    cp = map[c];
  1593. X    if (cp == 0) {
  1594. X        s_mess("[%sunbound]", key_strokes);
  1595. X        rbell();
  1596. X    } else
  1597. X        ExecCmd(cp);
  1598. X}
  1599. X
  1600. void
  1601. Yank()
  1602. X{
  1603. X    Line    *line,
  1604. X        *lp;
  1605. X    Bufpos    *dot;
  1606. X
  1607. X    if (killbuf[killptr] == 0)
  1608. X        complain("[Nothing to yank!]");
  1609. X    lsave();
  1610. X    this_cmd = YANKCMD;
  1611. X    line = killbuf[killptr];
  1612. X    lp = lastline(line);
  1613. X    dot = DoYank(line, 0, lp, length(lp), curline, curchar, curbuf);
  1614. X    set_mark();
  1615. X    SetDot(dot);
  1616. X}
  1617. X
  1618. void
  1619. WtModBuf()
  1620. X{
  1621. X    if (!ModBufs(NO))
  1622. X        message("[No buffers need saving]");
  1623. X    else
  1624. X        put_bufs(is_an_arg());
  1625. X}
  1626. X
  1627. void
  1628. put_bufs(askp)
  1629. X{
  1630. X    register Buffer    *oldb = curbuf,    
  1631. X            *b;        
  1632. X
  1633. X    for (b = world; b != 0; b = b->b_next) {
  1634. X        if (!IsModified(b) || b->b_type != B_FILE)
  1635. X            continue;
  1636. X        SetBuf(b);    /* Make this current Buffer */
  1637. X        if (curbuf->b_fname == 0) {
  1638. X            char    *newname;
  1639. X
  1640. X            newname = ask(NullStr, "Buffer \"%s\" needs a file name; type Return to skip: ", b->b_name);
  1641. X            if (*newname == 0)
  1642. X                continue;
  1643. X            setfname(b, newname);
  1644. X        }
  1645. X        if (askp && (yes_or_no_p("Write %s? ", curbuf->b_fname) == NO))
  1646. X            continue;
  1647. X        filemunge(curbuf->b_fname);
  1648. X#ifndef MAC
  1649. X#ifndef MSDOS
  1650. X        chk_mtime(curbuf, curbuf->b_fname, "save");
  1651. X#endif /* MSDOS */
  1652. X#endif /* MAC */
  1653. X        file_write(curbuf->b_fname, 0);
  1654. X        unmodify();
  1655. X    }
  1656. X    SetBuf(oldb);
  1657. X}
  1658. X
  1659. void
  1660. ToIndent()
  1661. X{
  1662. X    register char    *cp,
  1663. X            c;
  1664. X
  1665. X    for (cp = linebuf; c = *cp; cp++)
  1666. X        if (c != ' ' && c != '\t')
  1667. X            break;
  1668. X    curchar = cp - linebuf;
  1669. X}
  1670. X
  1671. X/* GoLine -- go to a line, usually wired to goto-line, ESC g or ESC G.
  1672. X   If no argument is specified it asks for a line number. */
  1673. void
  1674. GoLine()
  1675. X{
  1676. X      Line    *newline;
  1677. X
  1678. X#ifndef ANSICODES
  1679. X     if (!is_an_arg())
  1680. X         set_arg_value(ask_int("Line: ",10));
  1681. X#else /* not ANSICODES */
  1682. X     if (!is_an_arg() || arg_value() <= 0) {
  1683. X          if (SP) {
  1684. X              putpad(SP, 1);    /* Ask for cursor position */
  1685. X            return;
  1686. X        }
  1687. X         set_arg_value(ask_int("Line: ", 10));
  1688. X      }
  1689. X#endif /* ANSICODES */
  1690. X     newline = next_line(curbuf->b_first, arg_value() - 1);
  1691. X      PushPntp(newline);
  1692. X      SetLine(newline);
  1693. X}
  1694. X
  1695. X#ifdef ANSICODES
  1696. void
  1697. MoveToCursor(line, col)
  1698. X{
  1699. X    register struct scrimage *sp = &PhysScreen[line];
  1700. X
  1701. X    while (sp->s_id == 0)
  1702. X        sp = &PhysScreen[--line];
  1703. X    if (sp->s_flags & MODELINE)
  1704. X        complain((char *) 0);
  1705. X    if (curwind != sp->s_window)
  1706. X        SetWind(sp->s_window);
  1707. X    SetLine(sp->s_lp);
  1708. X    curchar = how_far(sp->s_lp, col);
  1709. X}
  1710. X
  1711. void
  1712. AnsiCodes()
  1713. X{
  1714. X    int    c;
  1715. X    int    num1 = 0;
  1716. X    int    num2;
  1717. X    static char *unsupported = "[Unsupported ANSI code received]";
  1718. X
  1719. X    while (isdigit(c = getch()))
  1720. X        num1 = (num1 * 10) + (c - '0');
  1721. X
  1722. X    switch (c) {
  1723. X    case ';':
  1724. X        num2 = 0;
  1725. X        while (isdigit(c = getch()))
  1726. X            num2 = (num2 * 10) + (c - '0');
  1727. X        switch (c) {
  1728. X        case 'R':
  1729. X            MoveToCursor(--num1, --num2);
  1730. X            break;
  1731. X        case 'H':
  1732. X            Eow();
  1733. X            Bol();
  1734. X            break;
  1735. X        default:
  1736. X            complain(unsupported);
  1737. X        }
  1738. X        break;
  1739. X    case 'A':
  1740. X        PrevLine();
  1741. X        break;
  1742. X    case 'B':
  1743. X        NextLine();
  1744. X        break;
  1745. X    case 'C':
  1746. X        ForChar();
  1747. X        break;
  1748. X    case 'D':
  1749. X        BackChar();
  1750. X        break;
  1751. X    case 'H':
  1752. X        Bow();
  1753. X        break;
  1754. X    case 'J':
  1755. X        if (num1 == 2) {
  1756. X            ClAndRedraw();
  1757. X            break;
  1758. X        }
  1759. X    case 'z':    /* Sun function keys send <esc>[Nz */
  1760. X        switch(num1) {
  1761. X            case 193:    /* L2 */
  1762. X                SetMark();
  1763. X                break;
  1764. X            case 194:    /* L3 */
  1765. X                PopMark();
  1766. X                break;
  1767. X            case 195:    /* L4 */
  1768. X                DelReg();
  1769. X                break;
  1770. X            case 208:    /* R1 */
  1771. X                QRepSearch();
  1772. X                break;
  1773. X            case 209:    /* R2 */
  1774. X                IncFSearch();
  1775. X                break;
  1776. X            case 210:    /* R3 */
  1777. X                WtModBuf();
  1778. X                break;
  1779. X            case 211:    /* R4 */
  1780. X                RepSearch();
  1781. X                break;
  1782. X            case 212:    /* R5 */
  1783. X                IncRSearch();
  1784. X                break;
  1785. X            case 213:    /* R6 */
  1786. X                Leave();
  1787. X                break;
  1788. X            case 214:    /* R7 */
  1789. X                BackWord();
  1790. X                break;
  1791. X            case 215:    /* R8 == UpArrow */
  1792. X                break;
  1793. X            case 216:    /* R9 */
  1794. X                ForWord();
  1795. X                break;
  1796. X            case 217:    /* R10 == LeftArrow */
  1797. X                break;
  1798. X            case 218:    /* R11 */
  1799. X                NextWindow();
  1800. X                break;
  1801. X            case 219:    /* R12 == RightArrow */
  1802. X                break;
  1803. X            case 220:    /* R13 */
  1804. X            case 221:    /* R14 == DownArrow */
  1805. X                break;
  1806. X            case 222:    /* R15 */
  1807. X            case 225:    /* F2 */
  1808. X            case 226:    /* F3 */
  1809. X            case 227:    /* F4 */
  1810. X                break;
  1811. X            case 228:    /* F5 */
  1812. X                break;
  1813. X            case 229:    /* F6 */
  1814. X                break;
  1815. X            case 230:    /* F7 */
  1816. X                break;
  1817. X            case 231:    /* F8 */
  1818. X                break;
  1819. X            case 232:    /* F9 */
  1820. X                break;
  1821. X            default:
  1822. X                num1 = -1;    /* Hack flags failure */
  1823. X                break;
  1824. X        }
  1825. X        if (num1 >= 0)
  1826. X            break;
  1827. X    case 'P':
  1828. X        PrevPage();
  1829. X        break;
  1830. X
  1831. X    case 'Q':
  1832. X        NextPage();
  1833. X        break;
  1834. X
  1835. X    case 'R':
  1836. X        UpScroll();
  1837. X        break;
  1838. X
  1839. X    case 'S':
  1840. X        DownScroll();
  1841. X        break;
  1842. X    default:
  1843. X        complain(unsupported);
  1844. X    }
  1845. X}
  1846. X#endif /* ANSICODES */
  1847. X
  1848. void
  1849. NotModified()
  1850. X{
  1851. X    unmodify();
  1852. X}
  1853. X
  1854. void
  1855. SetLMargin()
  1856. X{
  1857. X    LMargin = calc_pos(linebuf, curchar);
  1858. X}
  1859. X
  1860. void
  1861. SetRMargin()
  1862. X{
  1863. X    RMargin = calc_pos(linebuf, curchar);
  1864. X}
  1865. END_OF_FILE
  1866. if test 7989 -ne `wc -c <'./misc.c'`; then
  1867.     echo shar: \"'./misc.c'\" unpacked with wrong size!
  1868. fi
  1869. # end of './misc.c'
  1870. fi
  1871. if test -f './wind.c' -a "${1}" != "-c" ; then 
  1872.   echo shar: Will not clobber existing file \"'./wind.c'\"
  1873. else
  1874. echo shar: Extracting \"'./wind.c'\" \(9907 characters\)
  1875. sed "s/^X//" >'./wind.c' <<'END_OF_FILE'
  1876. X/***************************************************************************
  1877. X * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  1878. X * is provided to you without charge, and with no warranty.  You may give  *
  1879. X * away copies of JOVE, including sources, provided that this notice is    *
  1880. X * included in all the files.                                              *
  1881. X ***************************************************************************/
  1882. X
  1883. X/* This creates/deletes/divides/grows/shrinks windows.  */
  1884. X
  1885. X#include "jove.h"
  1886. X#include "termcap.h"
  1887. X
  1888. private char    onlyone[] = "You only have one window!",
  1889. X        toosmall[] = "Resulting window would be too small.";
  1890. X
  1891. Window    *curwind,
  1892. X    *fwind = 0;
  1893. X
  1894. X/* First line in a Window */
  1895. X
  1896. int
  1897. FLine(w)
  1898. register Window    *w;
  1899. X{
  1900. X    register Window    *wp = fwind;
  1901. X    register int    lineno = -1;
  1902. X
  1903. X    do {
  1904. X        if (wp == w)
  1905. X            return lineno + 1;
  1906. X        lineno += wp->w_height;
  1907. X        wp = wp->w_next;
  1908. X    } while (wp != fwind);
  1909. X    complain("window?");
  1910. X    /* NOTREACHED */
  1911. X}
  1912. X
  1913. X/* Delete `wp' from the screen.  If it is the only window left
  1914. X   on the screen, then complain.  It gives its body
  1915. X   to the next window if there is one, otherwise the previous
  1916. X   window gets the body.  */
  1917. X
  1918. void
  1919. del_wind(wp)
  1920. register Window    *wp;
  1921. X{
  1922. X    register Window    *prev = wp->w_prev;
  1923. X
  1924. X    if (one_windp())
  1925. X        complain(onlyone);
  1926. X
  1927. X    wp->w_prev->w_next = wp->w_next;
  1928. X    wp->w_next->w_prev = wp->w_prev;
  1929. X    
  1930. X    if (fwind == wp) {
  1931. X        fwind = wp->w_next;
  1932. X        fwind->w_height += wp->w_height;
  1933. X        /* Here try to do something intelligent for redisplay() */
  1934. X        SetTop(fwind, prev_line(fwind->w_top, wp->w_height));
  1935. X        if (curwind == wp)
  1936. X            SetWind(fwind);
  1937. X    } else {
  1938. X        prev->w_height += wp->w_height;
  1939. X        if (curwind == wp)
  1940. X            SetWind(prev);
  1941. X    }
  1942. X#ifdef MAC
  1943. X    RemoveScrollBar(wp);
  1944. X    Windchange++;
  1945. X#endif
  1946. X    free((char *) wp);
  1947. X}
  1948. X
  1949. X/* Divide the window WP N times, or at least once.  Complains if WP is too
  1950. X   small to be split into that many pieces.  It returns the new window. */
  1951. X
  1952. Window *
  1953. div_wind(wp, n)
  1954. register Window    *wp;
  1955. X{
  1956. X    register Window    *new;
  1957. X    int    amt;
  1958. X
  1959. X    if (n < 1)
  1960. X        n = 1;
  1961. X    amt = wp->w_height / (n + 1);
  1962. X    if (amt < 2)
  1963. X        complain(toosmall);
  1964. X
  1965. X    while (--n >= 0) {
  1966. X        new = (Window *) emalloc(sizeof (Window));
  1967. X        new->w_flags = 0;
  1968. X        new->w_LRscroll = 0;
  1969. X
  1970. X        new->w_height = amt;
  1971. X        wp->w_height -= amt;
  1972. X
  1973. X        /* set the lines such that w_line is the center in
  1974. X           each Window */
  1975. X        new->w_line = wp->w_line;
  1976. X        new->w_char = wp->w_char;
  1977. X        new->w_bufp = wp->w_bufp;
  1978. X        new->w_top = prev_line(new->w_line, HALF(new));
  1979. X
  1980. X        /* Link the new window into the list */
  1981. X        new->w_prev = wp;
  1982. X        new->w_next = wp->w_next;
  1983. X        new->w_next->w_prev = new;
  1984. X        wp->w_next = new;
  1985. X#ifdef MAC
  1986. X        new->w_control = 0;
  1987. X#endif
  1988. X    }
  1989. X#ifdef MAC
  1990. X    Windchange++;
  1991. X#endif
  1992. X    return new;
  1993. X}
  1994. X
  1995. X/* Initialze the first window setting the bounds to the size of the
  1996. X   screen.  There is no buffer with this window.  See parse for the
  1997. X   setting of this window. */
  1998. X
  1999. void
  2000. winit()
  2001. X{
  2002. X    register Window    *w;
  2003. X
  2004. X    w = curwind = fwind = (Window *) emalloc(sizeof (Window));
  2005. X    w->w_line = w->w_top = 0;
  2006. X    w->w_LRscroll = 0;
  2007. X    w->w_flags = 0;
  2008. X    w->w_char = 0;
  2009. X    w->w_next = w->w_prev = fwind;
  2010. X    w->w_height = ILI;
  2011. X#ifdef MAC
  2012. X    w->w_control = 0;
  2013. X    Windchange++;
  2014. X#endif
  2015. X}
  2016. X
  2017. X/* Change to previous window. */
  2018. X
  2019. void
  2020. PrevWindow()
  2021. X{
  2022. X    register Window    *new = curwind->w_prev;
  2023. X
  2024. X    if (Asking)
  2025. X        complain((char *) 0);
  2026. X    if (one_windp())
  2027. X        complain(onlyone);
  2028. X    SetWind(new);
  2029. X}
  2030. X
  2031. X/* Make NEW the current Window */
  2032. X
  2033. void
  2034. SetWind(new)
  2035. register Window    *new;
  2036. X{
  2037. X    if (!Asking) {        /* can you say kludge? */
  2038. X        curwind->w_line = curline;
  2039. X        curwind->w_char = curchar;
  2040. X        curwind->w_bufp = curbuf;
  2041. X    }
  2042. X    if (new == curwind)
  2043. X        return;
  2044. X    SetBuf(new->w_bufp);
  2045. X    if (!inlist(new->w_bufp->b_first, new->w_line)) {
  2046. X        new->w_line = curline;
  2047. X        new->w_char = curchar;
  2048. X    }
  2049. X    DotTo(new->w_line, new->w_char);
  2050. X    if (curchar > strlen(linebuf))
  2051. X        new->w_char = curchar = strlen(linebuf);
  2052. X    curwind = new;
  2053. X}
  2054. X
  2055. X/* delete the current window if it isn't the only one left */
  2056. X
  2057. void
  2058. DelCurWindow()
  2059. X{
  2060. X    SetABuf(curwind->w_bufp);
  2061. X    del_wind(curwind);
  2062. X}
  2063. X
  2064. X/* put the current line of `w' in the middle of the window */
  2065. X
  2066. void
  2067. CentWind(w)
  2068. register Window    *w;
  2069. X{
  2070. X    SetTop(w, prev_line(w->w_line, HALF(w)));
  2071. X}
  2072. X
  2073. int    ScrollStep = 0;        /* full scrolling */
  2074. X
  2075. X/* Calculate the new topline of the window.  If ScrollStep == 0
  2076. X   it means we should center the current line in the window. */
  2077. X
  2078. void
  2079. CalcWind(w)
  2080. register Window    *w;
  2081. X{
  2082. X    register int    up;
  2083. X    int    scr_step;
  2084. X    Line    *newtop;
  2085. X
  2086. X    if (ScrollStep == 0)    /* Means just center it */
  2087. X        CentWind(w);
  2088. X    else {
  2089. X        up = inorder(w->w_line, 0, w->w_top, 0);
  2090. X        if (up == -1) {
  2091. X            CentWind(w);
  2092. X            return;
  2093. X        }
  2094. X        scr_step = (ScrollStep < 0) ? SIZE(w) + ScrollStep :
  2095. X               ScrollStep - 1;
  2096. X        if (up)        /* point is above the screen */
  2097. X            newtop = prev_line(w->w_line, scr_step);
  2098. X        else
  2099. X            newtop = prev_line(w->w_line, (SIZE(w) - 1 - scr_step));
  2100. X        if (LineDist(newtop, w->w_top) >= SIZE(w) - 1)
  2101. X            CentWind(w);
  2102. X        else
  2103. X            SetTop(w, newtop);
  2104. X    }
  2105. X}
  2106. X
  2107. X/* This is bound to C-X 4 [BTF].  To make the screen stay the
  2108. X   same we have to remember various things, like the current
  2109. X   top line in the current window.  It's sorta gross, but it's
  2110. X   necessary because of the way this is implemented (i.e., in
  2111. X   terms of do_find(), do_select() which manipulate the windows. */
  2112. X
  2113. void
  2114. WindFind()
  2115. X{
  2116. X    register Buffer    *obuf = curbuf,
  2117. X            *nbuf;
  2118. X    Line    *ltop = curwind->w_top;
  2119. X    Bufpos    savedot;
  2120. X    extern void
  2121. X        FindTag(),
  2122. X        BufSelect(),
  2123. X        FindFile();
  2124. X
  2125. X    DOTsave(&savedot);
  2126. X
  2127. X    switch (waitchar((int *) 0)) {
  2128. X    case 't':
  2129. X    case 'T':
  2130. X        ExecCmd((data_obj *) FindCmd(FindTag));
  2131. X        break;
  2132. X
  2133. X    case 'b':
  2134. X    case 'B':
  2135. X        ExecCmd((data_obj *) FindCmd(BufSelect));
  2136. X        break;
  2137. X
  2138. X    case 'f':
  2139. X    case 'F':
  2140. X        ExecCmd((data_obj *) FindCmd(FindFile));
  2141. X        break;
  2142. X
  2143. X    default:
  2144. X        complain("T: find-tag, F: find-file, B: select-buffer.");
  2145. X    }
  2146. X
  2147. X    nbuf = curbuf;
  2148. X    SetBuf(obuf);
  2149. X    SetDot(&savedot);
  2150. X    SetTop(curwind, ltop);    /* there! it's as if we did nothing */
  2151. X
  2152. X    if (one_windp())
  2153. X        (void) div_wind(curwind, 1);
  2154. X
  2155. X    tiewind(curwind->w_next, nbuf);
  2156. X    SetWind(curwind->w_next);
  2157. X}
  2158. X
  2159. X/* Go into one window mode by deleting all the other windows */
  2160. X
  2161. void
  2162. OneWindow()
  2163. X{
  2164. X    while (curwind->w_next != curwind)
  2165. X        del_wind(curwind->w_next);
  2166. X}
  2167. X
  2168. Window *
  2169. windbp(bp)
  2170. register Buffer    *bp;
  2171. X{
  2172. X
  2173. X    register Window    *wp = fwind;
  2174. X
  2175. X    if (bp == 0)
  2176. X        return 0;
  2177. X    do {
  2178. X        if (wp->w_bufp == bp)
  2179. X            return wp;
  2180. X        wp = wp->w_next;
  2181. X    } while (wp != fwind);
  2182. X    return 0;
  2183. X}
  2184. X
  2185. X/* Change window into the next window.  Curwind becomes the new window. */
  2186. X
  2187. void
  2188. NextWindow()
  2189. X{
  2190. X    register Window    *new = curwind->w_next;
  2191. X
  2192. X    if (Asking)
  2193. X        complain((char *) 0);
  2194. X    if (one_windp())
  2195. X        complain(onlyone);
  2196. X    SetWind(new);
  2197. X}
  2198. X
  2199. X/* Scroll the next Window */
  2200. X
  2201. void
  2202. PageNWind()
  2203. X{
  2204. X    if (one_windp())
  2205. X        complain(onlyone);
  2206. X    NextWindow();
  2207. X    NextPage();
  2208. X    PrevWindow();
  2209. X}
  2210. X
  2211. Window *
  2212. w_nam_typ(name, type)
  2213. register char    *name;
  2214. X{
  2215. X    register Window *w;
  2216. X    register Buffer    *b;
  2217. X
  2218. X    b = buf_exists(name);
  2219. X    w = fwind;
  2220. X    if (b) do {
  2221. X        if (w->w_bufp == b)
  2222. X            return w;
  2223. X    } while ((w = w->w_next) != fwind);
  2224. X
  2225. X    w = fwind;
  2226. X    do {
  2227. X        if (w->w_bufp->b_type == type)
  2228. X            return w;
  2229. X    } while ((w = w->w_next) != fwind);
  2230. X
  2231. X    return 0;
  2232. X}
  2233. X
  2234. X/* Put a window with the buffer `name' in it.  Erase the buffer if
  2235. X   `clobber' is non-zero. */
  2236. X
  2237. void
  2238. pop_wind(name, clobber, btype)
  2239. register char    *name;
  2240. X{
  2241. X    register Window    *wp;
  2242. X    register Buffer    *newb;
  2243. X
  2244. X    if (newb = buf_exists(name))
  2245. X        btype = -1;    /* if the buffer exists, don't change
  2246. X                   it's type */
  2247. X    if ((wp = w_nam_typ(name, btype)) == 0) {
  2248. X        if (one_windp())
  2249. X            SetWind(div_wind(curwind, 1));
  2250. X        else
  2251. X            PrevWindow();
  2252. X    } else
  2253. X        SetWind(wp);
  2254. X
  2255. X    newb = do_select((Window *) 0, name);
  2256. X    if (clobber) {
  2257. X        initlist(newb);
  2258. X        newb->b_modified = NO;
  2259. X    }
  2260. X    tiewind(curwind, newb);
  2261. X    if (btype != -1)
  2262. X        newb->b_type = btype;
  2263. X    SetBuf(newb);
  2264. X}
  2265. X
  2266. void
  2267. GrowWindow()
  2268. X{
  2269. X    WindSize(curwind, abs(arg_value()));
  2270. X}
  2271. X
  2272. void
  2273. ShrWindow()
  2274. X{
  2275. X    WindSize(curwind, -abs(arg_value()));
  2276. X}
  2277. X
  2278. X/* Change the size of the window by inc.  First arg is the window,
  2279. X   second is the increment. */
  2280. X
  2281. void
  2282. WindSize(w, inc)
  2283. register Window    *w;
  2284. register int    inc;
  2285. X{
  2286. X    if (one_windp())
  2287. X        complain(onlyone);
  2288. X
  2289. X    if (inc == 0)
  2290. X        return;
  2291. X    else if (inc < 0) {    /* Shrinking this Window. */
  2292. X        if (w->w_height + inc < 2)
  2293. X            complain(toosmall);
  2294. X        w->w_height += inc;
  2295. X        w->w_prev->w_height -= inc;
  2296. X    } else            /* Growing the window. */
  2297. X        WindSize(w->w_next, -inc);
  2298. X#ifdef MAC
  2299. X    Windchange++;
  2300. X#endif
  2301. X}
  2302. X
  2303. X/* Set the topline of the window, calculating its number in the buffer.
  2304. X   This is for numbering the lines only. */
  2305. X
  2306. void
  2307. SetTop(w, line)
  2308. Window    *w;
  2309. register Line    *line;
  2310. X{
  2311. X    register Line    *lp = w->w_bufp->b_first;
  2312. X    register int    num = 0;
  2313. X
  2314. X    w->w_top = line;
  2315. X    if (w->w_flags & W_NUMLINES) {
  2316. X        while (lp) {
  2317. X            num += 1;
  2318. X            if (line == lp)
  2319. X                break;
  2320. X            lp = lp->l_next;
  2321. X        }
  2322. X        w->w_topnum = num;
  2323. X    }
  2324. X}
  2325. X
  2326. void
  2327. WNumLines()
  2328. X{
  2329. X    curwind->w_flags ^= W_NUMLINES; 
  2330. X    SetTop(curwind, curwind->w_top);
  2331. X}
  2332. X
  2333. void
  2334. WVisSpace()
  2335. X{
  2336. X    curwind->w_flags ^= W_VISSPACE;
  2337. X    ClAndRedraw();
  2338. X}
  2339. X
  2340. X/* Return the line number that `line' occupies in `windes' */
  2341. X
  2342. int
  2343. in_window(windes, line)
  2344. register Window    *windes;
  2345. register Line    *line;
  2346. X{
  2347. X    register int    i;
  2348. X    register Line    *top = windes->w_top;
  2349. X
  2350. X    for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next)
  2351. X        if (top == line)
  2352. X            return FLine(windes) + i;
  2353. X    return -1;
  2354. X}
  2355. X
  2356. void
  2357. SplitWind()
  2358. X{
  2359. X    SetWind(div_wind(curwind, is_an_arg() ? (arg_value() - 1) : 1));
  2360. X}
  2361. X
  2362. X/* Goto the window with the named buffer.  If no such window
  2363. X   exists, pop one and attach the buffer to it. */
  2364. void
  2365. GotoWind()
  2366. X{
  2367. X    extern Buffer    *lastbuf;
  2368. X    char    *bname;
  2369. X    Window    *w;
  2370. X
  2371. X    bname = ask_buf(lastbuf);
  2372. X    w = curwind->w_next;
  2373. X    do {
  2374. X        if (w->w_bufp->b_name == bname) {
  2375. X            SetABuf(curbuf);
  2376. X            SetWind(w);
  2377. X            return;
  2378. X        }
  2379. X        w = w->w_next;
  2380. X    } while (w != curwind);
  2381. X    SetABuf(curbuf);
  2382. X    pop_wind(bname, NO, -1);
  2383. X}
  2384. X
  2385. void
  2386. ScrollRight()
  2387. X{
  2388. X    int    amt = (is_an_arg() ? arg_value() : 10);
  2389. X
  2390. X    if (curwind->w_LRscroll - amt < 0)
  2391. X        curwind->w_LRscroll = 0;
  2392. X    else
  2393. X        curwind->w_LRscroll -= amt;
  2394. X    UpdModLine = YES;
  2395. X}
  2396. X
  2397. void
  2398. ScrollLeft()
  2399. X{
  2400. X    int    amt = (is_an_arg() ? arg_value() : 10);
  2401. X
  2402. X    curwind->w_LRscroll += amt;
  2403. X    UpdModLine = YES;
  2404. X}
  2405. END_OF_FILE
  2406. if test 9907 -ne `wc -c <'./wind.c'`; then
  2407.     echo shar: \"'./wind.c'\" unpacked with wrong size!
  2408. fi
  2409. # end of './wind.c'
  2410. fi
  2411. echo shar: End of archive 4 \(of 21\).
  2412. cp /dev/null ark4isdone
  2413. MISSING=""
  2414. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  2415.     if test ! -f ark${I}isdone ; then
  2416.     MISSING="${MISSING} ${I}"
  2417.     fi
  2418. done
  2419. if test "${MISSING}" = "" ; then
  2420.     echo You have unpacked all 21 archives.
  2421.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2422. else
  2423.     echo You still need to unpack the following archives:
  2424.     echo "        " ${MISSING}
  2425. fi
  2426. ##  End of shell archive.
  2427. exit 0
  2428.